package com.gss.plugin.oauth2.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gss.datasource.mapper.sys.SysDeptMapper;
import com.gss.datasource.mapper.sys.SysMenuMapper;
import com.gss.datasource.mapper.sys.SysRoleMapper;
import com.gss.datasource.mapper.sys.SysUserMapper;
import com.gss.entity.enums.ConstantEnum;
import com.gss.entity.sys.dto.SysDept;
import com.gss.entity.sys.dto.SysRole;
import com.gss.entity.sys.dto.SysUser;
import com.gss.plugin.oauth2.exception.CustomAuthException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: DYang
 * @since: 2023/8/18
 * @description:
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private SysMenuMapper menuMapper;
    @Autowired
    private SysRoleMapper roleMapper;
    @Autowired
    private SysDeptMapper deptMapper;
    @Autowired
    private SysUserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username));
        if (user == null) {
            throw new CustomAuthException(ConstantEnum.NO_USER);
        }
        //获取资源
        String resource ;
        if ("super".equals(username)){
            resource = "userId:["+ user.getId() +"],super";
        }else {
            //获取用户所属部门
            List<SysDept> deptList = deptMapper.getDeptEnableListByUserId(user.getId());
            if (CollUtil.isEmpty(deptList)) {
                //部门不存在
                throw new CustomAuthException(ConstantEnum.NO_DEPT);
            }
            List<Integer> deptIdList = deptList.stream().map(SysDept::getId).collect(Collectors.toList());
            //获取用户权限
            List<SysRole> roleList = roleMapper.listRoleEnableByDeptId(deptIdList);
            if (ObjectUtil.isEmpty(roleList)) {
                //角色不存在
                throw new CustomAuthException(ConstantEnum.NO_ROLE);
            }
            // 构建资源
            resource = this.buildResource(user,deptList,roleList);
//            // 获取资源
//            List<Integer> roleIdList = roleList.stream().map(SysRole::getId).collect(Collectors.toList());
//            List<SysMenu> menuList = menuMapper.listMenuEnableByRoleId(roleIdList);
//            if (CollUtil.isEmpty(menuList)) {
//                //资源不存在
//                throw new CustomAuthException(ConstantEnum.NO_RESOURCE);
//            }
//            //资源code
//            resource = menuList.stream().map(SysMenu::getRoute).collect(Collectors.joining(","));
        }

        List<SimpleGrantedAuthority> authorityList = Arrays.stream(resource.split(",")).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
        //获取资源
        return new User(user.getUserName(), user.getPassword(), authorityList);
    }

    /**
     * 构建资源信息
     * @param user
     * @param deptList
     * @param roleList
     * @return
     */
    private String buildResource(SysUser user, List<SysDept> deptList, List<SysRole> roleList) {
        StringBuilder builder = new StringBuilder();
        builder.append("userId:[").append(user.getId()).append("],");
        builder.append("dept:[");
        // 部门
        for (int i = 0; i < deptList.size(); i++) {
            SysDept sysDept = deptList.get(i);
            if (i != 0) {
                builder.append(":");
            }
            builder.append(sysDept.getDeptCode());
        }
        builder.append("]");
        // 角色
        for (SysRole sysRole : roleList) {
            builder.append(",").append(sysRole.getRoleCode());
        }
        return builder.toString();
    }
}